home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 1 Issue 2
/
PDCD-1 - Issue 02.iso
/
_utilities
/
utilities
/
001
/
fue
/
c
/
riscos
< prev
next >
Wrap
Text File
|
1991-06-24
|
20KB
|
816 lines
/*
* This defines Archimedes screen-handling and spawning fns - div
* (based on vt52.c & msdos files, so not necessarily the way i
would have done it - might redo it when i understand it !)
*/
#define termdef 1 /* don't define "term" external */
/*{{{ include files*/
#include <stdio.h>
#include <kernel.h>
#include <time.h>
#include "estruct.h"
#include "etype.h"
#include "edef.h"
#include "elang.h"
/*}}}*/
/*{{{ part one - terminal control stuff*/
#if RISCOS
/*{{{ various #defines*/
#define NROW 31 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 500 /* # times thru update to pause */
#define ESC 0x1B /* ESC character. */
#define BEL 0x07 /* ascii bell character */
/*}}}*/
/*{{{ function prototypes*/
extern int ttopen(); /* Forward references. */
extern int ttgetc();
extern int ttputc();
extern int ttflush();
extern int ttclose();
extern int armmove();
extern int armeeol();
extern int armeeop();
extern int armbeep();
extern int armopen();
extern int armrev();
extern int armcres();
extern int armkopen();
extern int armkclose();
#if COLOR
extern int armfcol();
extern int armbcol();
#endif
/*}}}*/
/*{{{ despatch table*/
/*
* Dispatch table. All the
* hard fields just point into the
* terminal I/O code.
*/
TERM term = {
NROW-1,
NROW-1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
NPAUSE,
armopen,
ttclose,
armkopen,
armkclose,
ttgetc,
ttputc,
ttflush,
armmove,
armeeol,
armeeop,
armbeep,
armrev,
armcres
#if COLOR
, armfcol,
armbcol
#endif
};
/*}}}*/
/*{{{ the functions*/
/*{{{ armmove(row, col)*/
armmove(row, col)
{
_kernel_oswrch(31);
_kernel_oswrch(col);
_kernel_oswrch(row);
}
/*}}}*/
/*{{{ armeeol()*/
armeeol()
{
_kernel_oswrch(23); _kernel_oswrch(8); /* vdu 23,8.. clears block */
_kernel_oswrch(5); _kernel_oswrch(6); /* 5,6 = current posn->eol */
_kernel_oswrch(0); _kernel_oswrch(0); /* lots of zeroes means no */
_kernel_oswrch(0); _kernel_oswrch(0); /* offsets involved */
_kernel_oswrch(0); _kernel_oswrch(0);
}
/*}}}*/
/*{{{ armeeop()*/
armeeop()
{
#if COLOR
armbcol(gbcolor); /* seem to need this - dunno why ! */
#endif
_kernel_oswrch(23); _kernel_oswrch(8); /* vdu 23,8 clears a block */
_kernel_oswrch(5); _kernel_oswrch(10); /* from curent posn to eop */
_kernel_oswrch(0); _kernel_oswrch(0); /* start at current posn */
_kernel_oswrch(0); _kernel_oswrch(0);
_kernel_oswrch(0); _kernel_oswrch(0);
}
/*}}}*/
/*{{{ armrev(status)*/
armrev(status) /* set the reverse video state */
int status; /* TRUE = reverse video, FALSE = normal video */
{ static int rev_vid=FALSE;
if (status != rev_vid)
{ _kernel_oswrch(23); _kernel_oswrch(17);
_kernel_oswrch(5); _kernel_oswrch(0);
_kernel_oswrch(0); _kernel_oswrch(0);
_kernel_oswrch(0); _kernel_oswrch(0);
_kernel_oswrch(0); _kernel_oswrch(0);
rev_vid=status;
}
}
/*}}}*/
/*{{{ armcres()*/
armcres(res)
char *res;
{ int i=0;
printf("[cres %s]", res);
if ( (strcmp(res, "0")) && ( (i=asc_int(res))==0))
return(FALSE);
scinit(i);
return(TRUE);
}
/*}}}*/
/*{{{ spal()*/
spal() /* change palette string */
{
/* Does nothing here */
}
/*}}}*/
#if COLOR
/*{{{ armfcol()*/
armfcol(colour) /* set the forground color */
int colour;
{
_kernel_oswrch(17); _kernel_oswrch(colour);
}
/*}}}*/
/*{{{ armbcol()*/
armbcol(colour) /* set the background color */
int colour;
{
_kernel_oswrch(17); _kernel_oswrch(colour | 128);
}
/*}}}*/
#endif
/*{{{ armbeep()*/
armbeep()
{
#ifdef BEL
ttputc(BEL);
ttflush();
#endif
}
/*}}}*/
/*{{{ armopen()*/
armopen()
{
scinit(-1);
ttopen();
}
/*}}}*/
/*{{{ armkopen()*/
armkopen()
{
}
/*}}}*/
/*{{{ armkclose()*/
armkclose()
{
}
/*}}}*/
#if FLABEL
/*{{{ fnclabel(f, n)*/
fnclabel(f, n) /* label a function key */
int f,n; /* default flag, numeric argument [unused] */
{
/* on machines with no function keys...don't bother */
return(TRUE);
}
/*}}}*/
#endif
/*}}}*/
#else
/*{{{ armhello()*/
armhello()
{
}
/*}}}*/
#endif
/*}}}*/
/*{{{ part two - lowlevel stuff (fn spawning, etc)*/
/*
* This bit is based on msdos.c
* I may tidy up when i get round to understanding how it all works
*/
/*{{{ Mouse stuff*/
/* The Mouse driver only works with typeahead defined */
#if MOUSE
#undef TYPEAH
#define TYPEAH 1
#endif
/*}}}*/
/* Some global variable */
#define INBUFSIZ 40
static int mexist; /* is the mouse driver installed? */
static int nbuttons; /* number of buttons on the mouse */
static int oldbut; /* Previous state of mouse buttons */
/* input buffers and pointers */
#define IBUFSIZE 64 /* this must be a power of 2 */
unsigned char in_buf[IBUFSIZE]; /* input character buffer */
int in_next = 0; /* pos to retrieve next input character */
int in_last = 0; /* pos to place most recent input character */
/*{{{ in_init()*/
in_init() /* initialize the input buffer */
{
in_next = in_last = 0;
}
/*}}}*/
/*{{{ in_check()*/
in_check() /* is the input buffer non-empty? */
{
if (in_next == in_last)
return(FALSE);
else
return(TRUE);
}
/*}}}*/
/*{{{ in_put(event)*/
in_put(event)
int event; /* event to enter into the input buffer */
{
in_buf[in_last++] = event;
in_last &= (IBUFSIZE - 1);
}
/*}}}*/
/*{{{ int in_get()*/
int in_get() /* get an event from the input buffer */
{
register int event; /* event to return */
event = in_buf[in_next++];
in_next &= (IBUFSIZE - 1);
return(event);
}
/*}}}*/
/*{{{ stuff to set up the keyboard*/
/* This is for setting up the keyboard...
*fx 4,2 sets cursor keys as fn keys
*fx 220,0 makes ^@ the escape key (change to no interrupt when working)
*fx 221 to *fx 228 control action of blocks of 16 codes above &80
*fx 238 sets the base of the numeric keypad
*fx 254 sets action of control on num keys
*/
static unsigned char armswis[]=
{4, 221, 222 ,223, 224, 225, 226, 227, 228, 229, 238, 254 };
static unsigned char armvals[]=
{2, 0xc0, 0xd0, 0xe0, 0xf0, 0x80, 0x90, 0xa0, 0xb0, 1, 0xc0, 0};
#define no_fxs (sizeof(armswis))
static armstore[no_fxs];
/*}}}*/
/*{{{ PASCAL NEAR ttopen()*/
PASCAL NEAR ttopen()
/*
* This function is called once to set up the terminal device streams.
*/
{ _kernel_swi_regs regs;
int i;
/* on all screens we are not sure of the initial position
of the cursor */
ttrow = 999;
ttcol = 999;
for (i=0; i<no_fxs; ++i)
{ regs.r[0]=armswis[i];
regs.r[1]=armvals[i];
regs.r[2]=0;
_kernel_swi(6, ®s, ®s);
armstore[i]=regs.r[1];
}
}
/*}}}*/
/*{{{ maxlines(lines)*/
maxlines(lines) /* set number of vertical rows for mouse */
int lines; /* # of vertical lines */
{
}
/*}}}*/
/*{{{ PASCAL NEAR ttclose()*/
PASCAL NEAR ttclose()
/*
* This function gets called just before we go back home to the command
* interpreter. On VMS it puts the terminal back in a reasonable state.
* Another no-operation on CPM.
*/
{ _kernel_swi_regs regs;
int i;
for (i=0; i<no_fxs; ++i)
{ regs.r[0]=armswis[i];
regs.r[1]=armstore[i];
regs.r[2]=0;
_kernel_swi(6, ®s, ®s);
}
}
/*}}}*/
/*{{{ PASCAL NEAR ttputc(c)*/
PASCAL NEAR ttputc(c)
/*
* Write a character to the display. On VMS, terminal output is buffered, and
* we just put the characters in the big array, after checking for overflow.
* On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
* MS-DOS (use the very very raw console output routine).
*/
{
_kernel_oswrch(c);
}
/*}}}*/
/*{{{ PASCAL NEAR ttflush()*/
PASCAL NEAR ttflush()
/*
* Flush terminal buffer. Does real work where the terminal output is buffered
* up. A no-operation on systems where byte at a time terminal I/O is done.
*/
{
}
/*}}}*/
/*{{{ int doschar()*/
int doschar() /* call the dos to get a char */
{ int mask=SPEC; /* only used if a fn key */
int num;
if ((num=_kernel_osrdch()) < 0x80 ) return(num);
/* its a control key - have a look at shift/ctrl and set flags */
num -= 0x80;
/*{{{ register shift and control bits*/
if (num & 0x10) num -= 0x10, mask|=SHFT;
if (num & 0x20) num -= 0x20, mask|=CTRL;
/*}}}*/
/* this seems the way to do it ??? */
in_put(mask>>8);
/*{{{ map keypad 2,4,6,8 to cursor keys*/
switch (num)
{ case 0x42 : in_put('E'); return(0); /* keypad 2 = down */
case 0x44 : in_put('C'); return(0); /* keypad 4 = left */
case 0x46 : in_put('D'); return(0); /* keypad 6 = right */
case 0x48 : in_put('F'); return(0); /* keypad 4 = up */
}
/*}}}*/
/*{{{ map other keys to useful FN names*/
if (num < 10) in_put(num+'0'); /* fn keys are FN0 to FN9 */
else if (num < 16) in_put(num-10+'A'); /* cursor keys are FNA to FNF */
else in_put(num - 0x40 + 'G'); /* num keypad is FNG to ... */
/*}}}*/
return(0); /* tell it that a special code is waiting in the buffer */
}
/*}}}*/
/*{{{ PASCAL NEAR ttgetc()*/
PASCAL NEAR ttgetc()
/*
* Read a character from the terminal, performing no editing and doing no echo
* at all. Also mouse events are forced into the input stream here.
*/
{
register int c; /* character read */
ttc: /* return any keystrokes waiting in the
type ahead buffer */
if (in_check())
return(in_get());
if (typahead())
return(doschar());
/* with no mouse, this is a simple get char routine */
if (mexist == FALSE || mouseflag == FALSE)
return(doschar());
#if MOUSE
/* turn the mouse cursor on */
rg.x.ax = 1; /* Show Cursor */
int86(0x33, &rg, &rg);
/* loop waiting for something to happen */
while (TRUE) {
if (typahead())
break;
if (checkmouse())
break;
}
/* turn the mouse cursor back off */
rg.x.ax = 2; /* Hide Cursor */
int86(0x33, &rg, &rg);
goto ttc;
#endif
}
/*}}}*/
/*{{{ scinit()*/
scinit(mode)
int mode; /* -1 means current mode */
{ static int dtype=-1; /* current mode */
if (mode==dtype)
return(FALSE);
_kernel_oswrch(22); _kernel_oswrch(mode);
sprintf(sres, "%d", dtype=mode); /* update $sres env var */
return(TRUE);
}
/*}}}*/
#if MOUSE
/*{{{ checkmouse()*/
checkmouse()
{
register int k; /* current bit/button of mouse */
register int event; /* encoded mouse event */
int newbut; /* new state of the mouse buttons */
int mousecol; /* current mouse column */
int mouserow; /* current mouse row */
int sstate; /* current shift key status */
/* check to see if any mouse buttons are different */
rg.x.ax = 3; /* Get button status and mouse position */
int86(0x33, &rg, &rg);
newbut = rg.x.bx;
mousecol = rg.x.cx >> 3;
mouserow = rg.x.dx >> 3;
/* get the shift key status as well */
sstate = 0;
rg.h.ah = 2; /* return current shift status */
int86(0x16, &rg, &rg);
sstate = rg.h.al;
for (k=1; k != (1 << nbuttons); k = k<<1) {
/* For each button on the mouse */
if ((oldbut&k) != (newbut&k)) {
/* This button changed, generate an event */
in_put(0);
in_put(MOUS >> 8);
in_put(mousecol);
in_put(mouserow);
event = ((newbut&k) ? 0 : 1); /* up or down? */
if (k == 2) /* center button? */
event += 4;
if (k == 4) /* right button? */
event += 2;
if (sstate & 3) /* shifted */
event += 'A';
else if (sstate & 4) /* controled? */
event += 1;
else
event += 'a'; /* plain */
in_put(event);
oldbut = newbut;
return(TRUE);
}
}
return(FALSE);
}
/*}}}*/
#endif
#if TYPEAH
/*{{{ PASCAL NEAR typahead()*/
PASCAL NEAR typahead()
/* typahead: Check to see if any characters are already in the
keyboard buffer
osbyte 152 returns carry set for an empty buffer
*/
{
return(!(_kernel_osbyte(152,0,0) >> 16));
}
/*}}}*/
#endif
/*{{{ PASCAL NEAR spawncli(f, n)*/
PASCAL NEAR spawncli(f, n)
/*
* Create a subjob with a copy of the command intrepreter in it. When the
* command interpreter exits, mark the screen as garbage so that you do a full
* repaint. Bound to "^X C".
*/
{
/* don't allow this command if restricted */
if (restflag)
return(resterr());
movecursor(term.t_nrow, 0); /* Seek to last line. */
TTflush();
TTkclose();
shellprog("");
TTkopen();
sgarbf = TRUE;
return(TRUE);
}
/*}}}*/
/*{{{ PASCAL NEAR spawn(f, n)*/
PASCAL NEAR spawn(f, n)
/*
* Run a one-liner in a subjob. When the command returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X !".
*/
{
register int s;
char line[NLINE];
/* don't allow this command if restricted */
if (restflag)
return(resterr());
if ((s=mlreply("!", line, NLINE)) != TRUE)
return(s);
movecursor(term.t_nrow - 1, 0);
TTkclose();
shellprog(line);
TTkopen();
/* if we are interactive, pause here */
if (clexec == FALSE) {
mlputs(TEXT6);
/* "\r\n\n[End]" */
tgetc();
}
sgarbf = TRUE;
return (TRUE);
}
/*}}}*/
/*{{{ PASCAL NEAR execprg(f, n)*/
PASCAL NEAR execprg(f, n)
/*
* Run an external program with arguments. When it returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X $".
*/
{
register int s;
char line[NLINE];
/* don't allow this command if restricted */
if (restflag)
return(resterr());
if ((s=mlreply("$", line, NLINE)) != TRUE)
return(s);
movecursor(term.t_nrow - 1, 0);
TTkclose();
execprog(line);
TTkopen();
/* if we are interactive, pause here */
if (clexec == FALSE) {
mlputs(TEXT6);
/* "\r\n\n[End]" */
tgetc();
}
sgarbf = TRUE;
return (TRUE);
}
/*}}}*/
/*{{{ PASCAL NEAR pipecmd(f, n)*/
PASCAL NEAR pipecmd(f, n)
/*
* Pipe a one line command into a window
* Bound to ^X @
*/
{
}
/*}}}*/
/*{{{ PASCAL NEAR filter(f, n)*/
PASCAL NEAR filter(f, n)
/*
* filter a buffer through an external DOS program
* Bound to ^X #
*/
{
}
/*}}}*/
/*{{{ PASCAL NEAR shellprog(cmd)*/
PASCAL NEAR shellprog(cmd)
/* SHELLPROG: Execute a command in a subshell */
char *cmd; /* Incoming command line to execute */
{
}
/*}}}*/
/*{{{ PASCAL NEAR execprog(cmd)*/
PASCAL NEAR execprog(cmd)
/* EXECPROG: A function to execute a named program
with arguments
*/
#if LATTICE | AZTEC | MWC
#define CFLAG 1
#endif
char *cmd; /* Incoming command line to execute */
{
}
/*}}}*/
/*{{{ char *PASCAL NEAR timeset()*/
char *PASCAL NEAR timeset()
/* return a system dependant string with the current time */
{ static char buffer[40];
time_t now;
time(&now);
if (strftime(buffer, 40, "%c", localtime(&now)))
return (buffer);
return (NULL);
}
/*}}}*/
/* FILE Directory routines */
#if COMPLET & (TURBO)
char path[NFILEN]; /* path of file to find */
char rbuf[NFILEN]; /* return file buffer */
/*{{{ char *PASCAL NEAR getffile(fspec)*/
char *PASCAL NEAR getffile(fspec)
/* do a wild card directory search (for file name completion) */
char *fspec; /* pattern to match */
{
register int index; /* index into various strings */
register int point; /* index into other strings */
register int extflag; /* does the file have an extention? */
char fname[NFILEN]; /* file/path for DOS call */
/* first parse the file path off the file spec */
strcpy(path, fspec);
index = strlen(path) - 1;
while (index >= 0 && (path[index] != '/' &&
path[index] != '\\' && path[index] != ':'))
--index;
path[index+1] = 0;
/* check for an extension */
point = strlen(fspec) - 1;
extflag = FALSE;
while (point >= 0) {
if (fspec[point] == '.') {
extflag = TRUE;
break;
}
point--;
}
/* construct the composite wild card spec */
strcpy(fname, path);
strcat(fname, &fspec[index+1]);
strcat(fname, "*");
if (extflag == FALSE)
strcat(fname, ".*");
/* and call for the first file */
if (findfirst(fname, &fileblock, 0) == -1)
return(NULL);
/* return the first file name! */
strcpy(rbuf, path);
strcat(rbuf, fileblock.ff_name);
mklower(rbuf);
return(rbuf);
}
/*}}}*/
/*{{{ char *PASCAL NEAR getnfile()*/
char *PASCAL NEAR getnfile()
{
register int index; /* index into various strings */
register int point; /* index into other strings */
register int extflag; /* does the file have an extention? */
char fname[NFILEN]; /* file/path for DOS call */
/* and call for the first file */
if (findnext(&fileblock) == -1)
return(NULL);
/* return the first file name! */
strcpy(rbuf, path);
strcat(rbuf, fileblock.ff_name);
mklower(rbuf);
return(rbuf);
}
/*}}}*/
#else
/*{{{ char *PASCAL NEAR getffile(fspec)*/
char *PASCAL NEAR getffile(fspec)
char *fspec; /* file to match */
{
return(NULL);
}
/*}}}*/
/*{{{ char *PASCAL NEAR getnfile()*/
char *PASCAL NEAR getnfile()
{
return(NULL);
}
/*}}}*/
#endif
/*}}}*/